package com.handinfo.uimenu.window;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import com.handinfo.engine.AbstractGameScreen;
import com.handinfo.game.ActorItem;
import com.handinfo.game.ActorRole;
import com.handinfo.game.RoleCombatSkill;
import com.handinfo.uimenu.UIAbstractWindow;
import com.handinfo.uimenu.UIManager;
import com.handinfo.uimenu.UITools;
import com.handinfo.util.Tools;

/**
 * 标签及背包的通用处理类
 * @author venizeng
 * 
 * 定义了对标签，背包格子的操作方法 其子类实现了对标签和背包格子的不同操作 本身应该通過介面具有介面
 */
public abstract class AbsLBHandler
{
	// 类型标示
	protected static final int TYPE_LABEL = 1;// 标签的标示
	protected static final int TYPE_BAG = 2;// 背包“格子”的标示，格子里可能放置道具，技能，还有function
	//
	protected static int NUM_BAG_ROW = 4;// 背包的行数
	protected static int NUM_BAG_COL = 9;// 背包的列数
	protected static final int NUM_BAG_DIS = NUM_BAG_ROW * NUM_BAG_COL;// 用于显示的背包数目
	// 按键处理类型
	protected static final int TYPE_DIR_NONE = -1;// 如果当前处理类抛出此类型，代表当前处理类未进行任何处理
	protected static final int TYPE_DIR_UNPRO = -2;// 代表当期处理类未作任何处理，同时阻断当前逻辑
	// 区域位置
	private final byte GROUPID_TOP = 1;
	private final byte GROUPID_LABEL = 2;
	private final byte GROUPID_BAG = 3;
	private final byte GROUPID_BOTTOM = 4;
	//
	protected final int W_BAG = UITools.W_BAG;
	protected final int H_BAG = UITools.H_BAG;
	protected final int IW_BAG = 2;
	protected final int IH_BAG = 2;
	protected final int RW_BAG = W_BAG + IW_BAG;
	protected final int RH_BAG = H_BAG + IH_BAG;

	// 标签和背包格子的起始Index
	protected int INDEX_LABEL_FIRST;// 若状态发生修改则起始索引可能发生修改
	protected int INDEX_BAG_FIRST;
	/**
	 * 每一个标签都有自己唯一的Id标示
	 */
	protected int m_id_label = -1;
	/**
	 * 标签的数目
	 */
	protected int m_num_label;
	/**
	 * 显示在最左最顶的一个格子的索引
	 */
	protected int m_index_data_top;
	/**
	 * 道具格子数据
	 */
	protected Object[] m_datas;
	/**
	 * 通过其获得界面类的信息
	 */
	private ILBHandler m_handler;

	public int m_row = NUM_BAG_ROW;
	/**
	 * 标签信息
	 */
	protected Image[] m_labels;
	protected int m_x_label;// 标签显示在界面中的位置
	protected int m_y_label;
	protected int m_w_label;// 标签的宽度
	protected int m_iw_label;// 标签的间隙
	// 标签显示在界面中的位置
	protected int m_x_bag;
	protected int m_y_bag;
	// 标签显示在界面中的位置
	protected int m_x_drag;
	protected int m_y_drag;
	protected int m_h_drag;
	protected int m_len_drag;// 下拉的百分比，每次背包的Index發生修改，修動態修改此值
	/**
	 * 背包焦点的起始位置 當處理類的標籤發生修改修修改焦點信息
	 */
	protected int m_x_fos = -1;
	protected int m_y_fos = -1;
	protected int m_w_fos = -1;
	protected int m_h_fos = -1;
	//
	protected int m_h_lb;
	// 当前界面信息，在发生updateOnStateOrIndexChanged时会将这些参数进行重设
	private int m_windowIndex = -1;// 可用于缓存，暂时不处理
	private int m_groupIndex = -1;
	private byte m_groupId = -1;
	private int m_index_label = -1;// 被选中标签的显示位置，对应没有被聚焦的情况
	protected int m_index_bag_sel = -1;// 選中的背包格子索引,移動的時候會用到

	public AbsLBHandler(ILBHandler iHandler)
	{
		m_handler = iHandler;
	}

	/**
	 * 当道具或者技能更新的时候需要将使用这些数据的界面进行更新 2012-2-16 下午02:46:51 venizeng
	 */
	public static void update()
	{
		UIAbstractWindow window = null;
		for (int i = 0, size = UIManager.getInstance().m_wins.size(); i < size; i++) {
			window = (UIAbstractWindow) UIManager.getInstance().m_wins.elementAt(i);
			if (window == null) {
				continue;
			}
			if (window instanceof ILBHandler) {
				window.updateWindow();
			}
		}
	}

	/**
	 * 当前界面State或者Index进行了修改，修改處理類内部信息2012-2-16 下午05:37:01 venizeng 在界面初始化的时候也需要对词条代码进行调用，获得初始数据
	 */
	public void updateOnStateOrIndexChanged()
	{
		// 初始化数据
		INDEX_LABEL_FIRST = m_handler.getFirstIndex(TYPE_LABEL);
		INDEX_BAG_FIRST = m_handler.getFirstIndex(TYPE_BAG);
		// 获得当前操作的是哪一个类型
		m_windowIndex = m_handler.getWindowIndex();
		m_groupIndex = m_handler.getGroupIndex();
		if (m_windowIndex < INDEX_LABEL_FIRST) {// 小于标签
			m_groupId = GROUPID_TOP;
		}
		else if (m_windowIndex < INDEX_BAG_FIRST) {// 标签
			m_groupId = GROUPID_LABEL;
		}
		else if (m_windowIndex < INDEX_BAG_FIRST + m_row * NUM_BAG_COL) {// 背包格子
			m_groupId = GROUPID_BAG;
		}
		else {
			m_groupId = GROUPID_BOTTOM;// 大于标签
		}
		// 修改焦点位置
		countFosPos();
		// 修改当前標籤狀態，标签状态的修改会导致背包格子数据的修改
		if (m_groupId == GROUPID_LABEL) {
			int id_label = getLabelIdByLabelIndex(m_groupIndex);
			setLabelByLabelId(id_label);
		}
		// 修改下拉条
		if (m_groupId == GROUPID_BAG) {// 仅当背包格子索引发生修改时触发计算下拉条的百分比
			// int len = 0;
			// int bagDataIndex = getCurrentBagDataIndex() / NUM_BAG_COL;
			// len = (bagDataIndex * 100) / (ActorRole.NUM_BAG_GOODS / NUM_BAG_COL);

			updateLen();
		}
		// 修改标签的
		if (m_groupId == GROUPID_LABEL) {
			setLabelByGroupIndex(m_groupIndex);// 当标签发生修改时候，要修改当前标签对应的Id，及索引
		}
	}

	private void updateLen()
	{
//		int maxNum = 0;
//		if (m_datas == null) {
//			maxNum = ActorRole.s_num_open;
//		}
//		else {
//			maxNum = m_datas.length;
//		}
		int dataIndex = getCurrentBagDataIndex();
//		if (dataIndex >= maxNum-1) {
//			m_len_drag = 100;
//			return;
//		}
		int row = dataIndex / NUM_BAG_COL;
		int sumRow = (ActorRole.NUM_BAG_GOODS + NUM_BAG_COL - 1) / NUM_BAG_COL;
		if (row == 0) {
			m_len_drag = 0;
		}
		else if (row == sumRow-1) {
			m_len_drag = 100;
		}
		else {
			m_len_drag = (100 * (row+1)) / sumRow;
		}
	}

	/**
	 * 计算焦点的位置信息 2012-2-19 下午04:50:41 venizeng
	 */
	private void countFosPos()
	{
		switch (m_groupId) {
			case GROUPID_LABEL:
				m_x_fos = m_x_label + m_groupIndex * (m_w_label + m_iw_label);
				m_y_fos = m_y_label;
				m_w_fos = m_w_label;
				m_h_fos = UITools.H_LABEL;
				break;
			case GROUPID_BAG:
				m_x_fos = m_x_bag + (m_groupIndex % NUM_BAG_COL) * (RW_BAG);
				m_y_fos = m_y_bag + (m_groupIndex / NUM_BAG_COL) * RH_BAG;
				m_w_fos = W_BAG;
				m_h_fos = H_BAG;
				break;
			default:
				m_x_fos = -1;
				m_y_fos = -1;
				m_w_fos = -1;
				m_h_fos = -1;
				break;
		}
	}

	/**
	 * 设置标签初始化位置，背包格子依赖于此位置进行计算 2012-2-16 下午05:35:05 venizeng
	 * @param y
	 */
	public void setInitXY(int y)
	{
		UIAbstractWindow window = (UIAbstractWindow) m_handler;
		int x = ((window.m_w - (m_num_label * (m_w_label + m_iw_label) - m_iw_label)) >> 1);
		setInitXY(x, y);
	}

	/**
	 * 设置标签在界面中显示的位置，背包和下拉條，選中都是按照這個來計算 2012-2-16 下午03:17:33 venizeng
	 */
	private void setInitXY(int x, int y)
	{
		if (m_y_label == y) {// 如已经设置，返回
			return;
		}
		m_x_label = ((UIAbstractWindow) m_handler).m_x + x;
		m_y_label = y;

		int h_label = UITools.H_LABEL + UITools.IH_RECTS;

		m_x_bag = m_x_label + 4;
		m_y_bag = m_y_label + h_label;

//		m_x_drag = ((UIAbstractWindow) m_handler).m_x + ((UIAbstractWindow) m_handler).m_w
//				- UIManager.getColorsWinBorder().length - UIManager.IMAGE_SCROLL_ARR.getWidth();

		m_x_drag = m_x_bag + (NUM_BAG_COL * (W_BAG + IW_BAG) - IW_BAG);

		// m_x_bag = UITools.getDragX(((UIAbstractWindow) m_handler).m_x, ((UIAbstractWindow) m_handler).m_w) ;
		m_y_drag = m_y_bag;
		m_h_drag = m_row * H_BAG + (NUM_BAG_ROW - 1) * IH_BAG;

		//
		countFosPos();
		//
		m_h_lb = h_label + m_h_drag;
	}

	/**
	 * 設置某一個背包格子被選中，適用於移動 2012-2-16 下午04:41:19 venizeng
	 * @param index
	 */
	public void setBagSelIndex(int index)
	{
		m_index_bag_sel = index;
	}

	/**
	 * 取消选中索引 2012-2-18 上午05:21:15 venizeng
	 */
	public void setBagSelIndexNone()
	{
		m_index_bag_sel = -1;
	}

	public int getBagSelIndex()
	{
		return m_index_bag_sel;
	}

	/**
	 * 绘制标签
	 * @param g
	 * @param x 起始位置
	 * @param y
	 */
	public void paintLabel(Graphics g)
	{
		int tempX = m_x_label;
		int tempY = m_y_label;
		int labelIndex = getLabelIndexByLabelId(m_id_label);
		boolean isFocusAble = m_groupId == GROUPID_LABEL;
		boolean isSel = false;
		for (int i = 0; i < m_num_label; i++) {
			Image label = m_labels[i];
			if (isFocusAble && (i == m_groupIndex)) {
				isSel = true;
			}
			else if (i == labelIndex) {
				isSel = true;
			}
			else {
				isSel = false;
			}
			UITools.paintLabelImage(g, tempX, tempY, m_w_label, UITools.H_LABEL, label, isSel);
			tempX += (m_w_label + m_iw_label);
		}
	}

	/**
	 * 绘制背包
	 * @param g
	 * @param x
	 * @param y
	 */
	public abstract void paintBag(Graphics g);

	/**
	 * 绘制背包
	 * @param g
	 * @param x
	 * @param y
	 */
	protected void paintActorItem(Graphics g)
	{
		int openDisIndex = ActorRole.s_num_open - m_index_data_top;
		int tempY = m_y_bag;
		ActorItem item = null;
		int num = 0;
		boolean isAll = getCurrentLabelId() == ActorItem.TYPE_GOODS_ALL;
		for (int i = 0; i < m_row; i++) {
			int tempX = m_x_bag;
			for (int j = 0; j < NUM_BAG_COL; j++) {
				if (m_datas == null) {
					item = null;
				}
				else {
					int tempNum = num + m_index_data_top;
					if (tempNum < 0 || tempNum >= m_datas.length) {
						item = null;
					}
					else {
						item = (ActorItem) m_datas[tempNum];
					}
				}
				UITools.paintActorItem(g, tempX, tempY, item, isAll && num == m_index_bag_sel, false,
						num < openDisIndex);
				num++;
				tempX += RW_BAG;
			}
			tempY += RH_BAG;
		}
	}

	protected void paintSkill(Graphics g)
	{
		int tempY = m_y_bag;
		// int focusDisIndex = getWindowIndex() - INDEX_BAG_FIRST;
		// boolean isFocused = (focusDisIndex >= 0 && focusDisIndex < NUM_BAG_DIS);
		RoleCombatSkill item = null;
		int num = 0;
		for (int i = 0; i < NUM_BAG_ROW; i++) {
			int tempX = m_x_bag;
			for (int j = 0; j < NUM_BAG_COL; j++) {
				g.drawImage(UIManager.IMAGE_ITEM_OPEN, tempX, tempY, 0);
				if (m_datas == null || num >= m_datas.length || m_datas[num] == null) {
					item = null;
				}
				else {
					item = (RoleCombatSkill) m_datas[num + m_index_data_top];
					item.drawIcon(g, tempX + 1, tempY + 1, Tools.LEFT_TOP);
				}
				num++;
				tempX += RW_BAG;
			}
			tempY += RH_BAG;
		}
	}

	/**
	 * 绘制选中情况(聚焦,選中) 2012-2-16 下午05:53:58 venizeng
	 * @param g
	 */
	public void paintBagFocused(Graphics g)
	{
		if (m_x_fos == -1 || m_y_fos == -1 || m_w_fos == -1 || m_h_fos == -1) {
			return;
		}
		UITools.paintFocusBox(g, m_x_fos, m_y_fos, m_w_fos, m_h_fos);
	}

	public void paintDrag(Graphics g)
	{
		UITools.paintScrollBar(g, m_x_drag, m_y_drag, m_h_drag, m_len_drag);
	}

	/**
	 * 绘制描述 2012-2-16 下午01:27:23 venizeng
	 * @param g
	 * @param w
	 * @param h
	 */
	public void paintDescribe(Graphics g)
	{
		if (m_x_fos == -1 || m_y_fos == -1 || m_w_fos == -1 || m_h_fos == -1) {
			return;
		}
		UITools.paintItemDescribe(g, m_x_fos, m_y_fos, ((UIAbstractWindow) m_handler).m_w,
				((UIAbstractWindow) m_handler).m_h, getCurrentBagItem());
	}

	/**
	 * 按键处理 2012-2-16 下午02:16:55 venizeng
	 * @param id_comp 当前是对标签还是对背包格子进行操作
	 * @return
	 */
	public int keyDir(int id_comp)
	{
		int index = 0;
		switch (id_comp) {
			case TYPE_BAG:
				index = keyDirOnBag();
				break;
			case TYPE_LABEL:
				index = keyDirOnLabel();
				break;
			default:
				Tools.debugPrintln("AbsLBHandler:无此Id");
				break;
		}
		return index;
	}

	/**
	 * 标签的处理逻辑 2012-2-19 上午11:57:53 venizeng
	 * @return
	 */
	protected int keyDirOnLabel()
	{
		if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_UP)) {
			return getUpIndex();
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_DOWN)) {
			return getDownIndex();
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_LEFT)) {
			int currentDisIndex = getGroupIndex();
			if (currentDisIndex == 0) {
				return INDEX_LABEL_FIRST + m_num_label - 1;
			}
			else {
				currentDisIndex--;
				return currentDisIndex + INDEX_LABEL_FIRST;
			}
//			if (currentDisIndex == 0) {
//				return getLeftIndex();
//			}
//			else {
//				currentDisIndex--;
//				return currentDisIndex + INDEX_LABEL_FIRST;
//			}
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_RIGHT)) {
			int currentDisIndex = getGroupIndex();
//			if (currentDisIndex == m_num_label) {
//				return getRightIndex();
//			}
//			else {
//				currentDisIndex++;
//				return currentDisIndex + INDEX_LABEL_FIRST;
//			}
			if (currentDisIndex == m_num_label - 1) {
				return INDEX_LABEL_FIRST;
			}
			else {
				currentDisIndex++;
				return currentDisIndex + INDEX_LABEL_FIRST;
			}

		}
		else {
			return TYPE_DIR_NONE;
		}
	}

	/**
	 * 背包格子的处理逻辑 2012-2-19 上午11:58:11 venizeng
	 * @return
	 */
	private int keyDirOnBag()
	{
		if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_UP)) {
			return keyBagUp();
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_DOWN)) {
			return keyDown();
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_LEFT)) {
			return keyBagLeft();
		}
		else if (AbstractGameScreen.haveKeyPressed(AbstractGameScreen.GK_RIGHT)) {
			return keyRight();
		}
		return TYPE_DIR_NONE;// 未作处理
	}

	protected abstract int keyRight();

	protected abstract int keyDown();

	protected void setTopDataIndex(int index)
	{
		if (index < 0) {
			throw new IllegalArgumentException("错误");
		}
		m_index_data_top = index;
		updateLen();
	}

	/**
	 * 背包格子的通用操作，设置栏和背包道具栏都是一直的 2012-2-19 上午11:53:02 venizeng
	 * @return
	 */
	protected int keyBagUp()
	{
		int bagDisIndex = getGroupIndex();
		if (bagDisIndex < NUM_BAG_COL) {// 显示最顶
			if (m_index_data_top <= 0) {// 数据最顶
				return getUpIndex();//
			}
			else {
				setTopDataIndex(m_index_data_top - NUM_BAG_COL);
			}
		}
		else {
			bagDisIndex -= NUM_BAG_COL;
		}
		return bagDisIndex + INDEX_BAG_FIRST;
	}

	/**
	 * 背包格子的通用操作，设置栏和背包道具栏都是一直的 2012-2-19 上午11:53:02 venizeng
	 * @return
	 */
	protected int keyBagLeft()
	{
		int bagDisIndex = getGroupIndex();
//		if (bagDisIndex == 0) {// 显示最上左
//			if (m_index_data_top == 0) {
//				return getLeftIndex();
//			}
//			else {
//				setTopDataIndex(m_index_data_top - NUM_BAG_COL);
//				bagDisIndex = NUM_BAG_COL - 1;
//			}
//		}
//		else {
//			bagDisIndex--;
//		}
		if (bagDisIndex % NUM_BAG_COL == 0) {
			bagDisIndex += (NUM_BAG_COL - 1);
		}
		else {
			bagDisIndex--;
		}
		return bagDisIndex + INDEX_BAG_FIRST;
	}

	/**
	 * 获得按下操作
	 */
	protected int keyBagDown()
	{
		int bagDisIndex = getGroupIndex();
		// 此处需考虑一下换行的问题
		if (m_index_data_top + bagDisIndex + NUM_BAG_COL >= ActorRole.s_num_open) {// 数据最下
			return getDownIndex();
		}
		else {
//			if (bagDisIndex >= (NUM_BAG_DIS - NUM_BAG_COL)) {// 显示最下
			if (bagDisIndex >= (m_row * NUM_BAG_COL - NUM_BAG_COL)) {// 显示最下
				setTopDataIndex(m_index_data_top + NUM_BAG_COL);
			}
			else {
				bagDisIndex += NUM_BAG_COL;
			}
		}
		return bagDisIndex + INDEX_BAG_FIRST;
	}

	/**
	 * 背包栏右
	 */
	protected int keyBagRight()
	{
		int bagDisIndex = getGroupIndex();
//		if (m_index_data_top + bagDisIndex >= ActorRole.s_num_open - 1) {// 数据最底
//			return getRightIndex();
//		}
//		else {
//			if (bagDisIndex == NUM_BAG_DIS - 1) {// 显示最下
//			// m_index_data_top += 1;
//				setTopDataIndex(m_index_data_top + NUM_BAG_COL);
//			}
//			else {
//				bagDisIndex++;
//			}
//		}
		int num = (NUM_BAG_COL - 1);
		if (bagDisIndex % NUM_BAG_COL == num) {
			bagDisIndex -= num;
		}
		else {
			bagDisIndex++;
		}
		return bagDisIndex + INDEX_BAG_FIRST;
	}

	/**
	 * 映射规则
	 * @param labelId
	 */
	protected abstract int getLabelIndexByLabelId(int labelId);

	/**
	 * 映射规则
	 * @param labelId
	 */
	protected abstract int getLabelIdByLabelIndex(int labelGroupIndex);

	/**
	 * 更具新的标签线索索引更新背包数据
	 * @param groupIndex
	 */
	public void setLabelByGroupIndex(int groupIndex)
	{
		int labelId = getLabelIdByLabelIndex(groupIndex);
		setLabelByLabelId(labelId);
	}

	public void setLabelByLabelId(int labelId)
	{
		if (m_id_label == labelId) {
			return;
		}
		m_id_label = labelId;
		m_index_label = getLabelIndexByLabelId(m_id_label);
		resetBagData();
		setTopDataIndex(0);
	}

	/**
	 * 过滤规则
	 * @return
	 */
	public Object[] filteDatas(Object datas)
	{
		return m_datas;
	}

	/**********/
	// Get
	/**********/
	/**
	 * 获得当前标签Id
	 */
	public int getCurrentLabelId()
	{
		return m_id_label;
	}

	/**
	 * 获得当前焦点格子的内容
	 * @return
	 */
	public Object getCurrentBagItem()
	{
		if (m_datas == null) {
			return null;
		}
		int bagDataIndex = getCurrentBagDataIndex();
		if (bagDataIndex < 0 || bagDataIndex >= m_datas.length) {
			return null;
		}
		return m_datas[bagDataIndex];
	}

	/**
	 * 获得当前背包数据索引 若焦点未聚焦在背包上返回null
	 * @return
	 */
	public int getCurrentBagDataIndex()
	{
		int windowIndex = getWindowIndex();
		if (windowIndex < INDEX_BAG_FIRST) {
			return -1;
		}
		int num = windowIndex - INDEX_BAG_FIRST;
		if (num >= m_row * NUM_BAG_COL) {
			return -1;
		}
		else {
			return num + m_index_data_top;
		}

//		return getGroupIndex() + m_index_data_top ;
	}

	/**
	 * 获得当前选中标签的WindowIndex
	 * @return
	 */
	public int getCurrentLabelWindowIndex()
	{
		return INDEX_LABEL_FIRST + m_index_label;
	}

	public int getDownIndex()
	{
		return m_handler.getDownIndex();
	}

	public int getGroupIndex()
	{
		return m_handler.getGroupIndex();
	}

	public int getLeftIndex()
	{
		return m_handler.getLeftIndex();
	}

	public int getRightIndex()
	{
		return m_handler.getRightIndex();
	}

	public int getUpIndex()
	{
		return m_handler.getUpIndex();
	}

	public int getWindowIndex()
	{
		return m_handler.getWindowIndex();
	}

	/**
	 * 当玩家背包发生修改时，需要对当前的道具数据进行修改 2012-2-19 下午12:09:58 venizeng
	 */
	public void resetBagData()
	{
		m_datas = m_handler.getBagDatas();
		m_datas = filteDatas(m_datas);
	}

	/**
	 * 得到处理类占屏幕的高度 2012-2-19 下午05:34:33 venizeng
	 * @return
	 */
	public int getLBHeight()
	{
		return m_h_lb;
	}

}
